using System;
using System.Collections;
using UnityEngine;

public class BaseWeapon : SynchronizedGameObject
{
	public bool shoot;

	public bool lastStart;

	public new string name;

	public string defaultName = string.Empty;

	public string nameSpritePreview;

	public string nameSpriteShootBtn = "Shot";

	[Space(10f)]
	public int idSorting;

	[HideInInspector]
	public bool isMobWeapon;

	public bool useLocalAmmo;

	public int _chargerAmmo;

	public int _ammo;

	public int maxChargerAmmo;

	public int maxAmmo = 999;

	private int maxAmmoAdder;

	public int addCountBulletBonuse;

	public int addCountBulletShop;

	[Space(10f)]
	public MechanickType mechanicType;

	public AimTypes aimType;

	public WeaponType weaponType;

	public WeaponTypeSpecific weaponTypeSpecific;

	public WeaponMarketType weaponMarketType;

	public BuffableWeaponType buffableWeaponType;

	public ShowAmmoType showAmmoType;

	[Space(10f)]
	public float damage = 1f;

	public float maxDistance = 100f;

	public float minDistance;

	[Space(10f)]
	public float _strength;

	public float minStrenght = 1f;

	public float strenghtGrowth = 1f;

	public float strenghtReduction = 1f;

	private float _spreadWeapon;

	[Space(10f)]
	public float minSpreadWeapon = 20f;

	private float maxSpreadWeaponMultiplier = 1f;

	public float maxSpreadWeapon = 100f;

	public float spreadReduction = 2f;

	public float spreadGrowth = 10f;

	[Space(10f)]
	private float minSpeedShootFactor = 1f;

	public float maxSpeedShootFactor = 1f;

	private float speedShootFactor = 1f;

	public float speedShootFactorGrowth;

	public float timeForStartShootFactorGrowth = 3f;

	private float timeShootFactorGrowth;

	public float timeForStartShootFactorReduction = 1f;

	private float timeShootFactorReduction;

	[Space(10f)]
	public int mobility = 100;

	private float mobilityMultiplier = 1f;

	private float timeBetweenShotsMultiplier = 1f;

	public float timeBetweenShots = 0.2f;

	public float reloadTime = 0.3f;

	private float reloadTimeMultiplier = 1f;

	public int bulletInOneShoot = 1;

	[Space(10f)]
	public Transform pointForShoot;

	public bool useAmmoForMultiplerShoot;

	[Space(10f)]
	public BaseCharge charge;

	[Space(10f)]
	public float timeDisabledShootParticle = 0.1f;

	public int emitParticleCount = 1;

	public ParticleSystem[] shootParticles;

	public ParticleSystem[] shootParticlesFPS;

	[Space(10f)]
	public bool dualWeapon;

	public bool showIfNoAmmo = true;

	public bool SaveBullet;

	[HideInInspector]
	[Space(10f)]
	public bool isShoting;

	[HideInInspector]
	public ButSelectWeapon butFotSelectThisWeapon;

	public WeaponMecanimWrapper _weaponMecanimWrapper;

	public WeaponAudio weaponAudio;

	[HideInInspector]
	public bool isReloading;

	public BaseWeapon secondWeapon;

	public GameObject secondWeaponPrefab;

	[Space(10f)]
	[HideInInspector]
	public Vector3 lastDamagePoint;

	[HideInInspector]
	public LayerMask lastShootingLayerMask;

	[HideInInspector]
	public bool lastStop = true;

	[HideInInspector]
	public bool inOpticalAIM;

	[HideInInspector]
	public Transform cameraTransform;

	private int cBulletInOneShoot = 1;

	private IEnumerator onlineShootIEnumerator;

	private Collider[] ignoreColliders;

	private bool _isMine;

	private Vector3 lastPos = Vector3.zero;

	private System.Random rnd = new System.Random();

	private bool LastShootThis;

	private float lastShootTime;

	public bool pool;

	private Vector3 endPoint;

	private float onlineUpdateTime = 0.05f;

	private bool fpsCameraEnabled;

	[SerializeField]
	private float _maxAccumulatorCharge;

	[SerializeField]
	private float _timeForMaxAccumulator;

	private float _currentTimeCharge;

	private float _currentAccumulator = 1f;

	private float damageMultiplier = 1f;

	private PlayerBehavior myPlayer;

	public int chargerAmmo
	{
		get
		{
			return (!isMobWeapon && !useLocalAmmo) ? BulletCountSaver.GetChargerAmmo(name) : _chargerAmmo;
		}
		set
		{
			if (!isMobWeapon && base.isMine && !useLocalAmmo)
			{
				BulletCountSaver.SetChargerAmmo(name, value);
			}
			else
			{
				_chargerAmmo = value;
			}
			RiseEvent(this, "ChangeChargerAmmo", value);
			RiseEvent(this, "ChangeAmmo", value);
			if (MaxAmmo > 0 && ammo == 0 && chargerAmmo == 0)
			{
				RiseEvent(this, "NoAmmoOnStart");
			}
		}
	}

	public int ammo
	{
		get
		{
			return (!isMobWeapon && !useLocalAmmo) ? Mathf.Clamp(BulletCountSaver.GetAmmo(name), 0, MaxAmmo) : _ammo;
		}
		set
		{
			_ammo = value;
			if (!isMobWeapon && !useLocalAmmo)
			{
				BulletCountSaver.SetAmmo(name, value);
			}
			RiseEvent(this, "ChangeAmmo", value);
			if (MaxAmmo > 0 && ammo == 0 && chargerAmmo == 0)
			{
				RiseEvent(this, "NoAmmoOnStart");
			}
		}
	}

	public int MaxAmmo
	{
		get
		{
			return maxAmmo + maxChargerAmmo * maxAmmoAdder;
		}
	}

	public float Damage
	{
		get
		{
			if (weaponTypeSpecific != WeaponTypeSpecific.Trebuchet)
			{
				return damage * damageMultiplier;
			}
			return TransformationChargeToDamage();
		}
	}

	public float strength
	{
		get
		{
			return _strength;
		}
		set
		{
			if (_strength != value)
			{
				RiseEvent(this, "ChangeStrength", (value - minStrenght) / (1f - minStrenght) / 100f * 100f);
				_strength = value;
			}
		}
	}

	public float spreadWeapon
	{
		get
		{
			return _spreadWeapon;
		}
		set
		{
			if (_spreadWeapon != value)
			{
				RiseEvent(this, "ChangeSpread", value);
				_spreadWeapon = value;
			}
		}
	}

	public float MaxSpreadWeapon
	{
		get
		{
			return maxSpreadWeapon / maxSpreadWeaponMultiplier;
		}
	}

	public int Mobility
	{
		get
		{
			float num = 1f;
			if (GameController.instance.curTypeGame == TypeGame.Zombe)
			{
				ZombeSettings zombeSettings = settings.GetSettings(TypeGame.Zombe) as ZombeSettings;
				num = ((TDMController.myTeam != PunTeams.Team.red) ? (zombeSettings.humanMoveMult * 1.2f) : zombeSettings.zombieMoveMult);
			}
			return Mathf.Clamp((int)((float)mobility * mobilityMultiplier * num), 0, 100);
		}
	}

	public float TimeBetweenShots
	{
		get
		{
			return timeBetweenShots / timeBetweenShotsMultiplier / speedShootFactor;
		}
	}

	public float ReloadTime
	{
		get
		{
			return reloadTime / reloadTimeMultiplier;
		}
	}

	public WeaponMecanimWrapper weaponMecanimWrapper
	{
		get
		{
			if (_weaponMecanimWrapper == null)
			{
				_weaponMecanimWrapper = GetComponent<WeaponMecanimWrapper>();
			}
			return _weaponMecanimWrapper;
		}
	}

	[HideInInspector]
	public int AllBullet
	{
		get
		{
			return BulletCountSaver.AllAmmo(name);
		}
	}

	[HideInInspector]
	public bool NoAmmo
	{
		get
		{
			return ammo + chargerAmmo == 0;
		}
	}

	protected Vector3 PointForShoot
	{
		get
		{
			if (inOpticalAIM)
			{
				return cameraTransform.position + Vector3.down * 0.2f;
			}
			return (!LastShootThis) ? pointForShoot.position : secondWeapon.pointForShoot.position;
		}
	}

	public bool needShow
	{
		get
		{
			if (showIfNoAmmo)
			{
				return name != string.Empty;
			}
			return (ammo != 0 || chargerAmmo != 0) && name != string.Empty;
		}
	}

	public int ViewID
	{
		get
		{
			if (GameController.instance.playerScript.isMine)
			{
				return GameController.instance.playerScript.viewId;
			}
			return -1;
		}
	}

	public bool canShoot
	{
		get
		{
			if (!base.gameObject.activeSelf)
			{
				return false;
			}
			return !isReloading && !isShoting;
		}
	}

	public override void Init()
	{
		base.Init();
		InitEvents(new string[16]
		{
			"NoAmmo", "OnlineShoot", "OnlineReload", "NoAmmoOnStart", "Reload", "EndReload", "ChangeAmmo", "Shoot", "Hit", "Damage",
			"StopShoot", "StartShoot", "ReduceAmmo", "ChangeStrength", "ChangeSpread", "ChangeChargerAmmo"
		});
	}

	public void Init(LayerMask layer, Transform holderRight, Transform weaponHolderLeft, Collider ignoreCollider, bool mobWeapon = false)
	{
		if (weaponAudio == null)
		{
			weaponAudio = GetComponent<WeaponAudio>();
		}
		if (pointForShoot == null)
		{
			pointForShoot = base.transform;
		}
		lastShootingLayerMask = layer;
		if (holderRight != null)
		{
			base.transform.parent = holderRight;
			base.transform.localPosition = Vector3.zero;
			base.transform.localRotation = Quaternion.identity;
			base.transform.localScale = Vector3.one;
		}
		if (dualWeapon)
		{
			if (secondWeapon == null)
			{
				if (secondWeaponPrefab != null)
				{
					secondWeapon = UnityEngine.Object.Instantiate(secondWeaponPrefab).GetComponent<BaseWeapon>();
				}
				else
				{
					secondWeapon = UnityEngine.Object.Instantiate(base.gameObject).GetComponent<BaseWeapon>();
				}
			}
			secondWeapon.transform.parent = weaponHolderLeft;
			secondWeapon.transform.localPosition = Vector3.zero;
			secondWeapon.transform.localRotation = Quaternion.identity;
			secondWeapon.transform.localScale = Vector3.one;
			secondWeapon.enabled = false;
			if (weaponMecanimWrapper._animatorLeft == null)
			{
				weaponMecanimWrapper._animatorLeft = secondWeapon.weaponMecanimWrapper._animatorLeft;
			}
		}
		charge.Init(this);
		charge.ignoreCollider = ignoreCollider;
		if (mobWeapon)
		{
			ownerViewId = -100;
		}
		if (weaponMecanimWrapper != null)
		{
			weaponMecanimWrapper.pullable = MechanickType.Charging == mechanicType;
		}
		if (!base.isMine && base.gameObject.activeInHierarchy)
		{
			if (onlineShootIEnumerator != null)
			{
				StopCoroutine(onlineShootIEnumerator);
			}
			else
			{
				onlineShootIEnumerator = OnlineShoot();
			}
			StopOnlineShoot();
			StartCoroutine(onlineShootIEnumerator);
		}
	}

	public void Init(LayerMask layer, Transform holderRight, Transform weaponHolderLeft, Collider[] ignoreColliders, bool mobWeapon = false)
	{
		Init(layer, holderRight, weaponHolderLeft, ignoreColliders[0], mobWeapon);
		charge.ignoreColliders = ignoreColliders;
	}

	public override void Awake()
	{
		base.Awake();
	}

	public override void Start()
	{
		cBulletInOneShoot = bulletInOneShoot;
		spreadWeapon = minSpreadWeapon;
		_isMine = base.isMine;
		StopShoot();
	}

	private void Update()
	{
		if (!_isMine || isMobWeapon)
		{
			return;
		}
		UpdateAccuracy();
		UpdateStrength();
		UpdateSpeedShoot();
		AccumulationOfCharge();
		if (MaxAmmo > 0 && chargerAmmo == 0)
		{
			Reload();
			lastShootTime = 0f;
			return;
		}
		switch (mechanicType)
		{
		case MechanickType.Auto:
			shoot = lastStart;
			break;
		case MechanickType.HalfAuto:
			shoot = lastStart;
			lastStart = false;
			break;
		case MechanickType.Charging:
			shoot = !lastStart && strength > minStrenght;
			break;
		}
		if (shoot)
		{
			Shoot(lastDamagePoint);
			if (mechanicType == MechanickType.Charging)
			{
				strength = minStrenght;
			}
			shoot = false;
		}
		else
		{
			lastShootTime = 0f;
		}
	}

	private void UpdateStrength()
	{
		if (isReloading)
		{
			strength = minStrenght;
		}
		else if (chargerAmmo != 0)
		{
			if (lastStart)
			{
				strength = Mathf.Clamp(strength + strenghtGrowth * Time.deltaTime, minStrenght, 1f);
			}
			else
			{
				strength = Mathf.Clamp(strength - strenghtReduction * Time.deltaTime, minStrenght, 1f);
			}
		}
	}

	private void UpdateAccuracy()
	{
		if (isReloading)
		{
			spreadWeapon = minSpreadWeapon;
			return;
		}
		float num = Vector3.Distance(lastPos, base.transform.position);
		spreadWeapon = Mathf.Clamp(spreadWeapon - spreadReduction * Time.deltaTime, minSpreadWeapon, MaxSpreadWeapon);
		if (num > 1f * Time.deltaTime && spreadWeapon < MaxSpreadWeapon / 4f)
		{
			spreadWeapon = Mathf.Clamp(spreadWeapon + spreadReduction * num * 10f * Time.deltaTime, minSpreadWeapon, MaxSpreadWeapon / 4f);
		}
		lastPos = base.transform.position;
	}

	private void UpdateSpeedShoot()
	{
		if (minSpeedShootFactor == maxSpeedShootFactor)
		{
			return;
		}
		if (timeShootFactorReduction >= timeForStartShootFactorReduction || isReloading)
		{
			speedShootFactor = minSpeedShootFactor;
			timeShootFactorGrowth = 0f;
			timeShootFactorReduction = 0f;
			return;
		}
		if (isShoting)
		{
			timeShootFactorGrowth = Mathf.Clamp(timeShootFactorGrowth + Time.deltaTime, 0f, timeForStartShootFactorGrowth);
			timeShootFactorReduction = 0f;
		}
		else
		{
			timeShootFactorReduction = Mathf.Clamp(timeShootFactorReduction + Time.deltaTime, 0f, timeForStartShootFactorReduction);
		}
		if (isShoting && timeShootFactorGrowth >= timeForStartShootFactorGrowth)
		{
			if (speedShootFactorGrowth > 0f)
			{
				speedShootFactor = Mathf.Clamp(speedShootFactor + speedShootFactorGrowth * Time.deltaTime, minSpeedShootFactor, maxSpeedShootFactor);
			}
			else
			{
				speedShootFactor = maxSpeedShootFactor;
			}
		}
	}

	private void AddSpread()
	{
		spreadWeapon += spreadGrowth;
	}

	public override void OnEnable()
	{
		if (MaxAmmo > 0 && ammo == 0 && chargerAmmo == 0)
		{
			RiseEvent(this, "NoAmmoOnStart");
		}
		RiseEvent(this, "ChangeChargerAmmo", chargerAmmo);
		if ((bool)secondWeapon)
		{
			secondWeapon.gameObject.SetActive(true);
		}
		if (!base.isMine)
		{
			if (onlineShootIEnumerator != null)
			{
				StopCoroutine(onlineShootIEnumerator);
			}
			else
			{
				onlineShootIEnumerator = OnlineShoot();
			}
			StopOnlineShoot();
			StartCoroutine(onlineShootIEnumerator);
		}
	}

	public override void OnDisable()
	{
		if ((bool)secondWeapon)
		{
			secondWeapon.gameObject.SetActive(false);
		}
		StopAllCoroutines();
		isShoting = false;
		isReloading = false;
		inOpticalAIM = false;
	}

	private float normalRandom(int dispers = 6)
	{
		float num = 0f;
		for (int i = 0; i < dispers; i++)
		{
			num += (float)rnd.NextDouble();
		}
		return (num / (float)dispers - 0.5f) * 2f;
	}

	protected Vector3 GetDirectionWithAccuracytyFromPoint(Vector3 startPoint, Vector3 endPoint, float spread, out float distance)
	{
		Vector3 vector = endPoint - startPoint;
		distance = Vector3.Distance(endPoint, startPoint);
		if (spread == 0f)
		{
			return vector.normalized;
		}
		float x = normalRandom() * spreadWeapon;
		float y = normalRandom() * spreadWeapon;
		float z = normalRandom() * spreadWeapon;
		Vector3 vector2 = new Vector3(x, y, z) * distance * 0.05f;
		return (vector + vector2).normalized;
	}

	public void StartShoot(Vector3 point)
	{
		lastDamagePoint = point;
		if (MaxAmmo > 0 && ammo == 0 && chargerAmmo == 0)
		{
			if (!isShoting)
			{
				RiseEvent(this, "NoAmmo");
				StartCoroutine(NoAmmoDelay());
			}
			StopShoot();
		}
		else if (lastStop)
		{
			if (isReloading)
			{
				RiseEvent(this, "StopShoot");
				return;
			}
			lastStop = false;
			lastStart = true;
			RiseEvent(this, "StartShoot");
		}
	}

	public void UpdateAmmo()
	{
		if (SaveBullet)
		{
			BulletCountSaver.SetStartAmmo(this);
		}
		RiseEvent(this, "ChangeAmmo", ammo);
		if (MaxAmmo > 0 && ammo == 0 && chargerAmmo == 0)
		{
			RiseEvent(this, "NoAmmoOnStart");
		}
	}

	public bool AddBulletFromShop()
	{
		if (ammo == MaxAmmo)
		{
			return false;
		}
		ammo = Mathf.Clamp(ammo + addCountBulletShop, 0, MaxAmmo);
		return MaxAmmo != 0 && showIfNoAmmo;
	}

	public bool AddBulletFromBonuse()
	{
		if (ammo == MaxAmmo)
		{
			return false;
		}
		ammo = Mathf.Clamp(ammo + addCountBulletBonuse, 0, MaxAmmo);
		return MaxAmmo != 0 && showIfNoAmmo;
	}

	public void StopShoot()
	{
		lastStart = false;
		lastStop = true;
		RiseEvent(this, "StopShoot");
	}

	protected void SimpleShoot(Vector3 pointShoot, Vector3 direction, float distance)
	{
		if (dualWeapon)
		{
			if (LastShootThis)
			{
				LastShootThis = false;
				secondWeapon.StartParticle();
			}
			else
			{
				LastShootThis = true;
				StartParticle();
			}
		}
		else
		{
			StartParticle();
		}
		charge.Shoot(Damage, strength, maxDistance, pointShoot, direction, lastShootingLayerMask, distance);
	}

	public virtual Vector3 Shoot(Vector3 point)
	{
		if (!canShoot)
		{
			cBulletInOneShoot = bulletInOneShoot;
			return Vector3.zero;
		}
		if (lastShootTime == 0f)
		{
			lastShootTime = Time.time;
		}
		else if (!isMobWeapon)
		{
			if (!PlayerBehavior.MyPlayer.inCar)
			{
				cBulletInOneShoot += Mathf.Clamp((int)((Time.time - lastShootTime) / TimeBetweenShots) - 1, 0, 50);
			}
			useAmmoForMultiplerShoot = bulletInOneShoot == 1;
			lastShootTime = Time.time;
		}
		float distance;
		Vector3 directionWithAccuracytyFromPoint = GetDirectionWithAccuracytyFromPoint(PointForShoot, point, spreadWeapon, out distance);
		SimpleShoot(PointForShoot, directionWithAccuracytyFromPoint, distance);
		cBulletInOneShoot--;
		if (cBulletInOneShoot > 0)
		{
			if (useAmmoForMultiplerShoot && MaxAmmo > 0)
			{
				chargerAmmo--;
			}
		}
		else if (MaxAmmo > 0)
		{
			chargerAmmo--;
		}
		if (cBulletInOneShoot >= 1 && (chargerAmmo > 0 || MaxAmmo == 0))
		{
			if (useAmmoForMultiplerShoot)
			{
				AddSpread();
			}
			Shoot(point);
		}
		else
		{
			cBulletInOneShoot = bulletInOneShoot;
			AddSpread();
			if (base.gameObject.activeSelf)
			{
				StartCoroutine(ShotDelay());
			}
		}
		if (SaveBullet)
		{
			BulletCountSaver.SaveConsumble(name);
		}
		if (chargerAmmo == 0 && MaxAmmo > 0)
		{
			Reload();
		}
		return directionWithAccuracytyFromPoint;
	}

	public void StartParticle()
	{
		ParticleSystem[] array = ((!fpsCameraEnabled) ? shootParticles : shootParticlesFPS);
		if (array != null)
		{
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Emit(emitParticleCount);
			}
			CancelInvoke("StopParticle");
		}
	}

	private void StopParticle()
	{
		for (int i = 0; i < shootParticles.Length; i++)
		{
			shootParticles[i].Stop();
		}
		for (int j = 0; j < shootParticlesFPS.Length; j++)
		{
			shootParticlesFPS[j].Stop();
		}
	}

	public bool isFullAmmo()
	{
		return ammo == MaxAmmo || SaveBullet;
	}

	public void RemoveWeapon()
	{
		if (weaponMecanimWrapper != null)
		{
			weaponMecanimWrapper.Unsubscribe();
		}
		RemoveAllEventsListeners();
		UnityEngine.Object.Destroy(base.gameObject);
	}

	public virtual void Reload()
	{
		if (ammo > 0 && !isReloading)
		{
			RiseEvent(this, "StopShoot");
			RiseEvent(this, "OnlineReload");
			StartCoroutine(ReloadDelay());
		}
	}

	protected IEnumerator ShotDelay()
	{
		isShoting = true;
		RiseEvent(this, "Shoot");
		yield return new WaitForSeconds(TimeBetweenShots);
		isShoting = false;
	}

	private IEnumerator NoAmmoDelay()
	{
		isShoting = true;
		yield return new WaitForSeconds(TimeBetweenShots);
		isShoting = false;
	}

	private IEnumerator ReloadDelay()
	{
		RiseEvent(this, "Reload");
		shoot = false;
		isReloading = true;
		yield return new WaitForSeconds(ReloadTime);
		isReloading = false;
		if (ammo - maxChargerAmmo < 0)
		{
			chargerAmmo = ammo;
		}
		else
		{
			chargerAmmo = maxChargerAmmo;
		}
		ammo -= chargerAmmo;
		RiseEvent(this, "EndReload");
	}

	private void OnDestroy()
	{
		if (weaponMecanimWrapper != null)
		{
			weaponMecanimWrapper.Unsubscribe();
		}
		RemoveAllEventsListeners();
		if (secondWeapon != null)
		{
			UnityEngine.Object.Destroy(secondWeapon.gameObject);
		}
		CancelInvoke("minusOneBullet");
		CancelInvoke("createThrowObj");
	}

	public void OnHit()
	{
		RiseEvent(this, "Hit");
	}

	public void OnDamage()
	{
		RiseEvent(this, "Damage");
	}

	public void StartPool()
	{
		pool = true;
	}

	public void StartOnlineShoot(Vector3 point)
	{
		RiseEvent(this, "StartShoot");
		lastStart = true;
		endPoint = point;
	}

	public void StopOnlineShoot()
	{
		pool = false;
		strength = minStrenght;
		RiseEvent(this, "StopShoot");
		lastStart = false;
	}

	public void StartOnlineReload(float time)
	{
		RiseEvent(this, "StopShoot");
		lastStart = false;
		strength = minStrenght;
		if (!isReloading && base.gameObject.activeSelf)
		{
			StartCoroutine(OnlineReloadDelay(time));
		}
	}

	private IEnumerator OnlineReloadDelay(float time)
	{
		yield return new WaitForSeconds(0.1f);
		RiseEvent(this, "Reload");
		isReloading = true;
		yield return new WaitForSeconds(time);
		isReloading = false;
		RiseEvent(this, "EndReload");
	}

	private IEnumerator OnlineShoot()
	{
		while (true)
		{
			if (pool)
			{
				strength = Mathf.Clamp(strength + strenghtGrowth * onlineUpdateTime, minStrenght, 1f);
			}
			if (lastStart && !isShoting && !isReloading)
			{
				Vector3 startpoint2 = pointForShoot.transform.position;
				if (dualWeapon)
				{
					if (LastShootThis)
					{
						LastShootThis = false;
						startpoint2 = secondWeapon.pointForShoot.transform.position;
						secondWeapon.StartParticle();
					}
					else
					{
						LastShootThis = true;
						StartParticle();
					}
				}
				else
				{
					StartParticle();
				}
				RiseEvent(this, "Shoot", endPoint);
				pool = false;
				strength = 0f;
				if (base.gameObject.activeSelf)
				{
					StartCoroutine(ShotDelay());
				}
			}
			yield return new WaitForSeconds(onlineUpdateTime);
		}
	}

	public void SwitchFPSCameraMode(bool enableFPS)
	{
		fpsCameraEnabled = enableFPS;
		weaponMecanimWrapper.SwitchFPSCameraMode(enableFPS);
		int layer = (enableFPS ? 29 : 0);
		Renderer[] componentsInChildren = GetComponentsInChildren<Renderer>(true);
		Renderer[] array = componentsInChildren;
		foreach (Renderer renderer in array)
		{
			renderer.gameObject.layer = layer;
		}
		if (secondWeapon != null)
		{
			componentsInChildren = secondWeapon.GetComponentsInChildren<Renderer>(true);
			Renderer[] array2 = componentsInChildren;
			foreach (Renderer renderer2 in array2)
			{
				renderer2.gameObject.layer = layer;
			}
		}
	}

	private void AccumulationOfCharge()
	{
		if (weaponTypeSpecific == WeaponTypeSpecific.Trebuchet && !isReloading && _currentTimeCharge <= _timeForMaxAccumulator)
		{
			_currentTimeCharge += Time.deltaTime;
			_currentAccumulator = Mathf.Lerp(1f, _maxAccumulatorCharge, _currentTimeCharge / _timeForMaxAccumulator);
		}
	}

	private void ResetCharge()
	{
		_currentTimeCharge = 0f;
		_currentAccumulator = 1f;
	}

	private float TransformationChargeToDamage()
	{
		float result = damage * damageMultiplier * _currentAccumulator;
		ResetCharge();
		return result;
	}

	public float PercentAccumulationCharge()
	{
		return _currentTimeCharge / _timeForMaxAccumulator;
	}

	public void SubscribeForEvent(PlayerBehavior player, bool subscribe)
	{
		if (subscribe)
		{
			myPlayer = player;
			myPlayer.refresSpecialProperties += RefreshDamageMultiplier;
			myPlayer.refresSpecialProperties += RefreshMobilityMultiplier;
			myPlayer.refresSpecialProperties += RefreshSpreadMultiplier;
			myPlayer.refresSpecialProperties += RefreshReloadTimeMultiplier;
			myPlayer.refresSpecialProperties += RefreshTimeBetweenShotsMultiplier;
			myPlayer.refresSpecialProperties += RefreshMaxAmmoAdder;
			RefreshDamageMultiplier();
			RefreshMobilityMultiplier();
			RefreshSpreadMultiplier();
			RefreshReloadTimeMultiplier();
			RefreshTimeBetweenShotsMultiplier();
			RefreshMaxAmmoAdder();
		}
		else
		{
			player.refresSpecialProperties -= RefreshDamageMultiplier;
			player.refresSpecialProperties -= RefreshMobilityMultiplier;
			player.refresSpecialProperties -= RefreshSpreadMultiplier;
			player.refresSpecialProperties -= RefreshReloadTimeMultiplier;
			player.refresSpecialProperties -= RefreshTimeBetweenShotsMultiplier;
			player.refresSpecialProperties -= RefreshMaxAmmoAdder;
			RiseEvent(this, "ChangeAmmo", ammo);
			myPlayer = null;
		}
	}

	private void RefreshDamageMultiplier()
	{
		damageMultiplier = myPlayer.GetWeaponDamageMultiplier(this);
	}

	private void RefreshMobilityMultiplier()
	{
		mobilityMultiplier = myPlayer.GetMobilityMultiplier();
	}

	private void RefreshSpreadMultiplier()
	{
		maxSpreadWeaponMultiplier = myPlayer.GetSpreadMultiplier();
	}

	private void RefreshReloadTimeMultiplier()
	{
		reloadTimeMultiplier = myPlayer.GetReloadTimeMultiplier();
	}

	private void RefreshTimeBetweenShotsMultiplier()
	{
		timeBetweenShotsMultiplier = myPlayer.GetTimeBetweenShotsMultiplier();
	}

	private void RefreshMaxAmmoAdder()
	{
		maxAmmoAdder = myPlayer.GetMaxAmmoAdder();
	}
}
